package com.cloudwave.trailends;


import java.util.List;

import android.app.ActivityManager;
import android.app.Application;
import android.app.PendingIntent;
import android.app.PendingIntent.CanceledException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.location.LocationManager;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.location.LocationClientOption.LocationMode;
import com.baidu.mapapi.SDKInitializer;
import com.cloudwave.trailends.domain.User;
import com.qiniu.android.storage.UploadManager;

public class AppContext extends Application {
	private static final String TAG = "TeApplication";
	public static final int NETTYPE_WIFI = 0x01;
	public static final int NETTYPE_CMWAP = 0x02;
	public static final int NETTYPE_CMNET = 0x03;
	
//	private static AppContext appInstance;  //为什幺要定义这个变量，并且是静态的？
	
	public static LocationClientOption locClientOption = null;
	
	/**
	 * KEY: FEebc32af263b572c2f35dae4e62aec4
	 * version: 2.1.3
	 * source：3kqing
	 */
	//这个参数应该有多重情况保证它的存在，并且可变
	//如果为空,则去百度网站爬来
//	public static final String bMapKey = "FEebc32af263b572c2f35dae4e62aec4";
	
	// 定位客户端
	private LocationClient locationClient = null;
	// 地理围栏客户端
//	private GeofenceClient geofenceClient;
	
	// 百度的KEY是否有效
//	private boolean bKeyValid = true;
	// 百度MapAPI的管理类
//	private BMapManager bMapManager;
//	private ACache mCache = null;
	private User loginUser = null;
//	private UserInfo loginUserInfo = null;
	private String token = null;
//	private LoginInfo loginInfo = null;
	
	
	private static UploadManager uploadManager;
	
//	public static AppContext getInstance() {
//		return appInstance;
//	}
	
	@Override
	public void onCreate() {
		super.onCreate();
		Log.v(TAG, "onCreate");
//		appInstance = this;
//		mCache = ACache.get(this);
		SDKInitializer.initialize(getApplicationContext());
		initLocator(this.getApplicationContext());
	}
	
//	public static ACache getACache() {
//		return getInstance().mCache == null ? ACache.get(getInstance()) : getInstance().mCache;
//	}
	/**
	 * 初始化定位客户端
	 */
	public static LocationClientOption getLocClientOption() {
		if (locClientOption == null) {
			locClientOption = new LocationClientOption();
		}
		locClientOption.setOpenGps(true); // 打开gps
//		locClientOption.setLocationMode(LocationMode.Device_Sensors);//仅用设备定位模式
		locClientOption.setLocationMode(LocationMode.Hight_Accuracy);//暂时使用高精度定位模式
		/**
		 高精度定位模式：这种定位模式下，会同时使用网络定位和GPS定位，优先返回最高精度的定位结果；
		低功耗定位模式：这种定位模式下，不会使用GPS，只会使用网络定位（Wi-Fi和基站定位）
		仅用设备定位模式：这种定位模式下，不需要连接网络，只使用GPS进行定位，这种模式下不支持室内环境的定位
		 */
//		locClientOption.setIsNeedAddress(true);//返回的定位结果包含地址信息
//		locClientOption.setAddrType("all");
		locClientOption.setNeedDeviceDirect(true);//返回的定位结果包含手机机头的方向
		locClientOption.setCoorType("bd09ll"); // 设置坐标类型
		locClientOption.setScanSpan(5000);// 定位的时间间隔，单位：ms
//		locClientOption.disableCache(true);//禁止启用缓存定位
//		locClientOption.setPoiNumber(5);    //最多返回POI个数
//		locClientOption.setPoiDistance(5000); //poi查询距离
//		locClientOption.setPoiExtraInfo(true); //是否需要POI的电话和地址等详细信息
//		locClientOption.setPriority(LocationClientOption.GpsFirst);  //设置GPS优先
		locClientOption.setProdName(Constants.APP_NAME); //设置产品线名称, 这个要问百度索取
		
		return locClientOption;
	}
	
	/**
	 * 初始化定位客户端
	 * @param context
	 */
	public void initLocator(Context context) {
		locationClient = new LocationClient(context);
//		locationClient.setAK(bMapKey);
//		locationClient.setLocOption(getLocClientOption());
//		geofenceClient = new GeofenceClient(context);
	}
	
	public LocationClient getLocationClient() {
		if (locationClient == null) {
			initLocator(this.getApplicationContext());
		}
		return locationClient;
	}
	
	public UploadManager getUploadManager() {
		if ( uploadManager == null ) {
			uploadManager = new UploadManager();
		}
		return uploadManager;
	}
	
	
	/**
	 * 检测某服务是否在运行
	 * @param context
	 * @param className
	 * @return
	 */
	public static boolean isServiceRunning(Context context, String className) {
		boolean isRunning = false;
		ActivityManager activityManager = (ActivityManager) context
				.getSystemService(Context.ACTIVITY_SERVICE);
		List<ActivityManager.RunningServiceInfo> serviceList = activityManager
				.getRunningServices(30);
		if (!(serviceList.size() > 0)) {
			return false;
		}
		for (int i = 0; i < serviceList.size(); i++) {
			if (serviceList.get(i).service.getClassName().equals(className) == true) {
				isRunning = true;
				break;
			}
		}
		return isRunning;
	}
	
	// 常用事件监听，用来处理通常的网络错误，授权验证错误等
//	static class BMapGeneralListener implements MKGeneralListener {
////		@Override
//		public void onGetNetworkState(int iError) {
//			Log.d(TAG, "onGetNetworkState error is "+ iError);
//			if (iError == MKEvent.ERROR_NETWORK_CONNECT) {
//				Toast.makeText(TeApplication.getInstance().getApplicationContext(), ":-( 网络连接出错啦!", Toast.LENGTH_SHORT).show();
//			} else if (iError == MKEvent.ERROR_NETWORK_DATA) {
//                Toast.makeText(TeApplication.getInstance().getApplicationContext(), "输入正确的检索条件！",
//                        Toast.LENGTH_SHORT).show();
//            }
//		}
//
////		@Override
//		public void onGetPermissionState(int iError) {
//			Log.d(TAG, "onGetPermissionState error is "+ iError);
//			if (iError == MKEvent.ERROR_PERMISSION_DENIED) {  //这个提示应该发送到服务器
//				Toast.makeText(TeApplication.getInstance().getApplicationContext(), "啥情况，又是百度SDK的Key授权失败，搞灰机啊!", Toast.LENGTH_SHORT).show();
//				TeApplication.getInstance().bKeyValid = false;
//			}
//		}
//	}

//	public GeofenceClient getGeofenceClient() {
//		return geofenceClient;
//	}

//	public boolean isbKeyValid() {
//		return bKeyValid;
//	}
	
	public int getVersionCode() {
		return getPackageInfo().versionCode;
	}
	public String getVersionName() {
		return getPackageInfo().versionName;
	}
	
	public String getAppMeta(String key) {
		ApplicationInfo appInfo = null;
		try {
			appInfo = getPackageManager().getApplicationInfo(getPackageName(),PackageManager.GET_META_DATA);
			return appInfo.metaData.getString(key);
		} catch (Exception e) {
			Toast.makeText(this, "获取应用信息失败~_~", Toast.LENGTH_SHORT).show();;
			Log.e(TAG, "获取Application配置信息失败!", e);
			return "unknow";
		}
	}

	/**
	 * 获取App安装包信息
	 * @return
	 */
	public PackageInfo getPackageInfo() {
		PackageInfo info = null;
		try { 
			info = getPackageManager().getPackageInfo(getPackageName(), 0);
		} catch (NameNotFoundException e) {    
			Toast.makeText(this, "获取应用信息失败~_~", Toast.LENGTH_SHORT).show();;
			Log.e(TAG, "获取当前应用版本信息失败!", e);
		} 
		if(info == null) info = new PackageInfo();
		return info;
	}
	
	/**
	 * 手机系统版本
	 */
	public static String getSdkVersion() {
		return android.os.Build.VERSION.RELEASE;
	}
	
	public TelephonyManager getTelephonyManager() {
		TelephonyManager phoneMgr = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
		return phoneMgr;
	}
	
	
	/**
	 * 检测网络是否可用
	 * @return
	 */
	public boolean isNetworkConnected() {
		ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo ni = cm.getActiveNetworkInfo();
		return ni != null && ni.isConnectedOrConnecting();
	}

	/**
	 * 获取当前网络类型
	 * @return 0：没有网络   1：WIFI网络   2：WAP网络    3：NET网络
	 */
	public int getNetworkType() {
		int netType = 0;
		ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
		if (networkInfo == null) {
			return netType;
		}		
		int nType = networkInfo.getType();
		if (nType == ConnectivityManager.TYPE_MOBILE) {
			String extraInfo = networkInfo.getExtraInfo();
			if(!TextUtils.isEmpty(extraInfo)){
				if (extraInfo != null && "cmnet".equalsIgnoreCase(extraInfo)) {
					netType = NETTYPE_CMNET;
				} else {
					netType = NETTYPE_CMWAP;
				}
			}
		} else if (nType == ConnectivityManager.TYPE_WIFI) {
			netType = NETTYPE_WIFI;
		}
		return netType;
	}
	
	/**
	 * 检测当前系统声音是否为正常模式
	 * @return
	 */
	public boolean isAudioNormal() {
		AudioManager mAudioManager = (AudioManager) getSystemService( AUDIO_SERVICE ); 
		return mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL;
	}
	
	/**
	 * 判断GPS是否开启
	 * @param context
	 * @return true 表示开启
	 */
	public static final boolean isOPen(final Context context) {
		LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
		// 通过GPS卫星定位，定位级别可以精确到街（通过24颗卫星定位，在室外和空旷的地方定位准确、速度快）
		boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
		// 通过WLAN或移动网络(3G/2G)确定的位置（也称作AGPS，辅助GPS定位。主要用于在室内或遮盖物（建筑群或茂密的深林等）密集的地方定位）
//		boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
//		if (gps || network) {
//			return true;
//		}

		return gps;
	}
	
	/**
	 * 强制帮用户打开GPS
	 * 使用系统自带的电量控制Widget来更改GPS的状态
	 * @param context
	 */
	public static final void openGPS(Context context) {
		Intent GPSIntent = new Intent();
		GPSIntent.setClassName("com.android.settings",
				"com.android.settings.widget.SettingsAppWidgetProvider");
		GPSIntent.addCategory("android.intent.category.ALTERNATIVE");
		GPSIntent.setData(Uri.parse("custom:3"));
		try {
			PendingIntent.getBroadcast(context, 0, GPSIntent, 0).send();
		} catch (CanceledException e) {
			Log.e(TAG, "调用系统设置面板异常:", e);
		}
	}

	public void setLoginUser(User user) {
		this.loginUser = user;
	}
	
	public void cacheLoginUser(User user) {
		this.loginUser = user;
		ACache c = ACache.get(this);
		
//		c.put(Constants.SIGNIN_TOKEN, user.getToken(), 60 * ACache.TIME_DAY);
//		c.put("user.id", user.getId().toString(), 60 * ACache.TIME_DAY);
//		c.put("user.email", user.getEmail(), 60 * ACache.TIME_DAY);
////		getACache().put("user.password", user.getPassword(), -1);
//		c.put("user.username", user.getUserName(), 60 * ACache.TIME_DAY);
//		c.put("user.avatarUrl", user.getAvatarUrl(), 60 * ACache.TIME_DAY);
//		String avatarLocalUrl = TextUtils.isEmpty(user.getLocalAvatar())?"":user.getLocalAvatar();
//		c.put("user.avatarLocalUrl", avatarLocalUrl, 60 * ACache.TIME_DAY);
		
		c.put(Constants.SESSION_USER, user, -1);
	}
	
	public User loadLoginUser() {
		if ( loginUser != null) {
			return loginUser;
		} else {
			ACache c = ACache.get(this);
//			String token = c.getAsString(Constants.SIGNIN_TOKEN);
//			if (TextUtils.isEmpty(token)) {
//				return null;
//			}
//			loginUser = new User();
//			loginUser.setToken(token);
//			Long userId = c.getAsString("user.id")==null?null:Long.parseLong(c.getAsString("user.id"));
//			loginUser.setId(userId);
//			loginUser.setUserName(c.getAsString("user.username"));
//			loginUser.setEmail(c.getAsString("user.email"));
//			loginUser.setAvatarUrl(c.getAsString("user.avatarUrl"));
//			loginUser.setLocalAvatar(c.getAsString("user.avatarLocalUrl"));
			
			loginUser = (User) c.getAsObject(Constants.SESSION_USER);
			
			return loginUser;
		}
	}
	
	public void updateLoginUser(User user) {
		this.loginUser = user;
		ACache c = ACache.get(this);
		c.put(Constants.SESSION_USER, user, -1);
	}
	
	public void clearLoginUser() {
		this.loginUser = null;
		this.token = null;
		ACache c = ACache.get(this);
		c.remove(Constants.SESSION_USER);
		
//		clearLoginUserInfo();
	}
	
	public boolean isLogin() {
		if ( this.loadLoginUser() == null ) {
			return false;
		} else {
			return true;
		}
	}
	
	public String getToken() {
		if (token != null) {
			return token;
		}
		User u = loadLoginUser();
		if ( u != null) {
			token = u.getToken();
			return token;
		}
		return null;
	}
	
	public Long getUid() {
		if ( loginUser != null) {
			return loginUser.getId();
		} else {
			User u = loadLoginUser();
			if ( u != null) {
				return u.getId();
			}
			return null;
		}
	}
	
//	public void setLoginUserInfo(UserInfo loginUserInfo) {
//		this.loginUserInfo = loginUserInfo;
//	}

//	public void cacheLoginUserInfo(UserInfo loginUserInfo) {
//		this.loginUserInfo = loginUserInfo;
//		ACache c = ACache.get(this);
//		c.put(Constants.SESSION_USER_INFO, loginUserInfo, -1);
//	}
//	
//	public UserInfo loadLoginUserInfo() {
//		if ( loginUserInfo != null) {
//			return loginUserInfo;
//		} else {
//			ACache c = ACache.get(this);
//			loginUserInfo = (UserInfo) c.getAsObject(Constants.SESSION_USER_INFO);
//			return loginUserInfo;
//		}
//	}
	
//	public void updateLoginUserInfo(UserInfo loginUserInfo) {
//		this.loginUserInfo = loginUserInfo;
//		ACache c = ACache.get(this);
//		c.put(Constants.SESSION_USER_INFO, loginUserInfo, -1);
//	}
//	
//	public void clearLoginUserInfo() {
//		this.loginUserInfo = null;
//		ACache c = ACache.get(this);
//		c.remove(Constants.SESSION_USER_INFO);
//	}
	
	public String getAsString(String key) {
		return ACache.get(this).getAsString(key);
	}
	public void put(String key, String value) {
		ACache.get(this).put(key, value, 60 * ACache.TIME_DAY);
	}

	
}
